package com.baidu.calculator;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 工具类
 * 工具类里面的工具都是共享的，不独属于某一个具体的对象
 * 所以工具类里面的方法通常都是静态方法
 */
public class CalculatorUtils {
    //运算
    public static float calculate(String operation,float num1, float num2){
        float result;

        if (operation.equals("＋")){
            result = num1 + num2;
        } else if (operation.equals("－")) {
            result = num1 - num2;
        }else if (operation.equals("×")) {
            result = num1 * num2;
        }else{
            result = num1 / num2;
        }
        return result;
    }

    //提取运算符
    public static ArrayList<String> collectOperation(String content){
        ArrayList<String> operationList = new ArrayList<>();
        for (int i = 0; i < content.length(); i++) {
            //获取i对应的字符
            char c = content.charAt(i);
            //将字符转化为字符串
            String cStr = String.valueOf(c);
            //判断是不是运算符
            if (isOperation(cStr)){
                operationList.add(cStr);
            }
        }
        return operationList;
    }

    //提取表达式中的数字
    //23.3 - 30 ÷ 3 x 2.33 + 234 - 98+1313
    //23.3
    public static ArrayList<Float> collectNumber(String content){
        //创建一个容器对象，用于存储提取过程中的数字
        ArrayList<Float> floatList = new ArrayList<>();

        //创建StringBuilder对象用于拼接运算数的字符串
        StringBuilder numberBuilder = new StringBuilder();

        //遍历数组
        for (int i = 0; i < content.length(); i++){
            //获取i对应的字符
            char c = content.charAt(i);
            //将字符转化为字符串
            String cStr = String.valueOf(c);
            //判断是不是运算符
            if (isOperation(cStr)){
                //当前这个是运算符
                //表示当前的运算数拼接结束，开始下一个新的运算数了
                //将当前的运算数转化为float类型保存到数组中
                Float num  = Float.valueOf(numberBuilder.toString());
                //保存到集合中
                floatList.add(num);
                //清空sb
                numberBuilder.setLength(0);
            }else{
                //这个是运算数
                //拼接
                numberBuilder.append(c);
            }
        }

        //判断最后一个元素是否有效
        if (numberBuilder.length() > 0){
            Float num  = Float.valueOf(numberBuilder.toString());
            floatList.add(num);
        }

        return floatList;
    }

    //将ArrayList<Float> 转化为 float[]
    private static float[] toFloatArray(ArrayList<Float> floatList){
        //方式1 一个一个转
        //创建一个普通数组，个数和原集合的个数一致
        float[] array = new float[floatList.size()];
        for (int i = 0; i < floatList.size(); i++) {
            array[i] = floatList.get(i);
        }
        return array;
    }

    //表达式当前的状态
    public static ExpressionStatus checkExpressionStatus(String content){
        if (content.isEmpty()){ //空
            return ExpressionStatus.NONE;
        }

        //有内容 3
        //0 1 2
        //获取最后一个字符
        String c = content.substring(content.length()-1);
        //判断字符是不是运算符
        if (isOperation(c)){
            return ExpressionStatus.OPERATION;
        }else{
            return ExpressionStatus.NUMBER;
        }
    }

    //判断输入的元素是不是运算数的组成部分
    //1+3*22
    //"1+3*2-323.32"
    //123
    //123.
    //1.是否有效 boolean
    //2.新的字符串对象 String
    public static CalculatorResult isNumberAppendingAvailable(String content,String str){
        //先创建一个返回的对象
        CalculatorResult result = new CalculatorResult();

        if (!str.equals(".")){ //不是小数点，
            //还需要判断最后一个元素是不是小数点 且 当前输入的是运算符
            if (content.endsWith(".") && isOperation(str)){
                //需要删除最后一个元素
                result.content = content.substring(0,content.length()-1);
                result.isAvailable = true;
                return result;
            }

            //78÷0+
            //除数不能为0 解决方案：移除除号和0
            //1. 当前输入的是运算符
            //2. 当前的数字是0
            //3. 数字前面是除法

            //1. 当前输入的是运算符
            if (isOperation(str)){
                //2. 当前的数字是0
                //3. 数字前面是除法
                if (content.endsWith("÷0")){
                    //移除 ÷0
                    result.content = content.substring(0,content.length()-2);
                }
                result.isAvailable = true;
                return result;
            }

            // 一个运算数中如果以0开始
            // 12+0  + 运算符 可以
            // 12+0  0 不可以
            // 12+0  2 替换这个0


            //判断是不是整个表达式的第一个元素
            //8
            if (content.length() == 1){
                if (content.endsWith("0")){
                    if (str.equals("0") || str.equals("00")){
                        //什么都不做
                        result.isAvailable = false;
                        return result;
                    }

                    //运算符直接拼接
                    if (isOperation(str)){
                        result.isAvailable = true;
                        return result;
                    }

                    //数字
                    //0 8
                    if ("123456789".contains(str)){
                        result.content = "";
                        result.isAvailable = true;
                        return result;
                    }
                }
            }else {
                //获取倒数第二个元素
                String c = String.valueOf(content.charAt(content.length() - 2));
                //判断最后一个元素是0 且 倒数第二个元素是运算符
                if (content.endsWith("0") && isOperation(c)) {
                    //如果自己输入的也是0或者00 不做任何事情
                    if (str.equals("0") || str.equals("00")) {
                        result.isAvailable = false;
                        return result;
                    }
                    //如果自己输入的1~9 直接替换
                    if ("123456789".contains(str)) {
                        result.content = content.substring(0, content.length() - 1);
                        result.isAvailable = true;
                        return result;
                    }
                }
            }


            result.isAvailable = true;
            return result;
        }

        //str已经是小数点了，才需要去查找最后一个运算数中是否有小数点
        for (int i = content.length()-1; i >= 0; i--){
            //取出i对应字符
            char c = content.charAt(i);
            //将字符转化为字符串
            String cStr = String.valueOf(c);
            //判断是不是运算符
            if (isOperation(cStr)){
                //说明最后一个运算数没有小数点，那么刚输入的内容直接拼接
                result.isAvailable = true;
                return result;
            }else{
                if (c == '.'){
                    result.isAvailable = false;
                   return result;
                }
            }
        }
        result.isAvailable = true;
        return result;
    }

    /**
     目前是运算符，判断此刻输入的内容是否可以完成拼接
     1+
     运算符 替换
     . 00 1~9 不需要任何处理，直接返回结果
     */
    public static CalculatorResult isOperationAppendingAvailable(String content, String str){
        //创建返回结果的对象
        CalculatorResult result = new CalculatorResult();

        //获取当前这个字符串的类型
        StringType type = checkContentType(str);

        //小数点 1+ .
        if (type == StringType.DOT){
            result.isAvailable = false;
            return result;
        }

        //00 1+ 00
        if(type == StringType.DOUBLE_ZERO){
            result.isAvailable = false;
            return result;
        }

        //1~9 1+ 2
        if (type == StringType.NUMBER){
            result.isAvailable = true;
            return result;
        }

        //运算符  123+ -
        //删掉当前这个运算符 然后返回
        result.isAvailable = true;
        result.content = content.substring(0,content.length()-1);
        return result;
    }

    //判断第一个元素是否合法
    public static boolean isFirstAvailable(String str){
        //获取当前这个字符串的类型
        StringType type = checkContentType(str);

        //如果是数字 表示有效
        if (type == StringType.NUMBER){
            return true;
        }else{ //否则就是小数点 00 运算符
            return false;
        }
    }

    //判断输入的内容的类型
    private static StringType checkContentType(String str){
       if (str.equals(".")){
           return StringType.DOT;
       } else if (str.equals("00")) {
           return StringType.DOUBLE_ZERO;
       } else if (isOperation(str)) {
           return StringType.OPERATION;
       } else{
           return StringType.NUMBER;
       }
    }

    //判断是不是运算符
    private static boolean isOperation(String str){
        //确保运算符和layout中一致
        String operation = "＋－×÷";

        return operation.contains(str);
    }


    public static ArrayList<String> extractNumbers(String expression) {
        // 使用正则表达式匹配数字（包括小数）
        Pattern pattern = Pattern.compile("\\d+\\.?\\d*");
        Matcher matcher = pattern.matcher(expression);

        ArrayList<String> list = new ArrayList<>();
        while (matcher.find()) {
            list.add(matcher.group(0));
        }

        return list;
    }

    public static ArrayList<String> extractOperation(String expression) {
        // 使用正则表达式匹配数字（包括小数）
        Pattern pattern = Pattern.compile("[+\\-×÷]");
        Matcher matcher = pattern.matcher(expression);

        ArrayList<String> list = new ArrayList<>();
        while (matcher.find()) {
            list.add(matcher.group(0));
        }

        return list;
    }
}
